package com.cloud.aiservice.controller;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.cloud.aiservice.entity.User;
import com.cloud.aiservice.entity.es.NewsRawEs;
import com.cloud.aiservice.feign.FileServieFeign;
import com.cloud.aiservice.mapper.UserMapper;
import com.cloud.aiservice.service.NewsSearchService;

import reactor.core.publisher.Mono;

@RestController
public class TestController {
	@Autowired
	private UserMapper userMapper;
	
	@Autowired
	private NewsSearchService newsSearchService;
	
	@Autowired
    public ElasticsearchOperations elasticsearchOperations;
	
//	@Autowired
	@Resource(name = "redisTemplate1")
	private RedisTemplate<String, Object> redisTemplate;
	
	@Autowired
	private FileServieFeign fileServieFeign;
	
	@Autowired
	private RestTemplate restTemplate;

	@RequestMapping("/")
	public String index() {
		return "Here is AI Service!";
	}
	
	@RequestMapping("/a2")
	public String aiFileNames() {
		return fileServieFeign.getFileList();
	}
	
	@RequestMapping("/ai")
	public String ai() {
		return restTemplate.getForObject("http://cloud-ali-fileservice//",  String.class);
	}
	
	@RequestMapping("/aiUser")
	public String aiUser() {
		StringBuilder res=new StringBuilder();
		Mono.fromCallable(()->{
			return userMapper.getAllUser().get(1).getUsername();
		}).doOnSuccess((s)->{
			s=s+"s";
			System.out.println(s);
		}).subscribe((s)-> res.append(s).append("kkk"), Throwable::printStackTrace);
		
		return res.toString();
	}
	
	@RequestMapping("/addUser")
	public String addAiUser(User u) {
//		var u=new User();
		if(userMapper.addUser(u)>0) {
			return "added User";
		}
		return "Failed to add user!";
	}
	
	@RequestMapping("/updateUser")
	public String updateUser(User u) {
//		var u=new User();
		u.setId(BigInteger.valueOf(7L));
		if(userMapper.updateUser(u)>0) {
			return "updated User";
		}
		
		return "Failed to add user!";
	}
	/**
	 * 反射例子
	 * @return
	 */
	@RequestMapping("/rUser")
	public String rUser(String username) {
		try {
			Class<?> cls=Class.forName("com.cloud.aiservice.entity.User");
			User ru=(User) cls.getDeclaredConstructor().newInstance();
			ru.setUsername(username+" is set");
			Method getUsername=cls.getMethod("getUsername");
			String ue=(String) getUsername.invoke(ru);
			new ConcurrentHashMap<>(32);
			return ue;
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return userMapper.getAllUser().get(1).getUsername();
	}
	
	@RequestMapping("/cache")
	@Cacheable(key = "#root.method",value="get-cache")
	public String cache() {
		System.out.println("Didn't enter cache");
		return userMapper.getAllUser().get(1).getUsername();
	}
	@RequestMapping("/redis")
	public String redis(String v) {
		if(StringUtils.isNotBlank(v)) {
			redisTemplate.opsForValue().set("redis", v);
			String s=(String)(redisTemplate.opsForValue().get("redis"));
			return s;
		}
		else {
			redisTemplate.opsForValue().append("redis", "大哥Virgil");
		}
		return "redis";
	}
	
	@GetMapping("/getNewsByKeyword")
	public String getNewsByKeyword(String keyword) {
		Criteria criteria = new Criteria("title").contains(keyword);
		Query query = new CriteriaQuery(criteria);
		SearchHits<NewsRawEs> searchHits=elasticsearchOperations.search(query,NewsRawEs.class);
		List<NewsRawEs> s=searchHits.get().map(hit->{
			return hit.getContent();
		}).collect(Collectors.toList());
//		operations.get("7", NewsRawEs.class);
		return newsSearchService.getNewsByKeyword(keyword);
//		return JSON.toJSONString(s);
	}	
}
